package com.yunjian.core.basic.service.impl;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.yunjian.core.basic.mapper.SSequenceMapper;
import com.yunjian.core.basic.model.SSequence;
import com.yunjian.core.basic.service.SequenceService;
import com.yunjian.core.basic.util.Constant;
import com.yunjian.util.DateUtil;
import com.yunjian.util.StringUtil;

@Service
public class SequenceServiceImpl implements SequenceService {

    private static Logger logger = LoggerFactory.getLogger(SequenceServiceImpl.class);

    @Autowired
    private SSequenceMapper sSequenceMapper;

    // 当前系统时间下一分钟的时间戳
    private static long NEXT_MINUTE_TIMESTAMP = 0L;
    // 当前系统时间字符串缓存（yyyyMMddHHmm精确到分钟）
    private static String CURRENT_MINUTE_STR = null;
    // 计数器最大值
    private final static int SEQ_MAX = Constant.SEQ_MAX;
    // 计数器最大值的长度
    private final static int SEQ_LENGTH = String.valueOf(SEQ_MAX).length();
    // 通用流水号计数器
    private static int COMMON_FLOW_SEQ = 0;

    @Override
    public String[] genCommonFlowNos(int num, String sysNo) {
        if (num < 1) {
            logger.error("num < 1");
            return null;
        }
        if (sysNo == null) {
            sysNo = "01";
        }
        String[] flowNos = new String[num];
        for (int i = 0; i < num; i++) {
            StringBuffer flowNoSB = new StringBuffer(32);
            flowNoSB.append(getTimeStr()); // 时间前缀
            String seqStr = String.valueOf(this.getCommonFlowNoSeq());
            seqStr = StringUtil.leftZero(seqStr, SEQ_LENGTH);
            flowNoSB.append(sysNo);
            flowNoSB.append(seqStr);
            flowNos[i] = flowNoSB.toString();
        }
        return flowNos;
    }

    @Override
    public String genCommonFlowNo(String sysNo) {
        return genCommonFlowNos(1, sysNo)[0];
    }

    /**
     * 获取时间yyyyMMddHHmmss字符串
     *
     * @return
     */
    private String getTimeStr() {
        if (System.currentTimeMillis() >= NEXT_MINUTE_TIMESTAMP) {
            // 生成新的时间字符串及下一分钟的时间戳缓存
            String timeTemp = DateUtil.getDate("yyyyMMddHHmm");
            Date currMin = DateUtil.formatDate(timeTemp);
            CURRENT_MINUTE_STR = timeTemp;
            NEXT_MINUTE_TIMESTAMP = currMin.getTime() + 60000;
        }
        return CURRENT_MINUTE_STR;
    }

    /**
     * 获取通用流水号的序列
     *
     * @return
     */
    private synchronized int getCommonFlowNoSeq() {
        if (++COMMON_FLOW_SEQ > SEQ_MAX) {
            COMMON_FLOW_SEQ = 0;
        }
        return COMMON_FLOW_SEQ;
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public String genFyNo() {
        StringBuffer sb = new StringBuffer("FY");
        sb.append(DateUtil.getDate("yyyyMMdd"));

        // 获取db序号
        String seqId = "FY_SEQUENCE";
        String seqStr = "";
        int up = sSequenceMapper.increaseByPrimaryKey(seqId);
        if (up != 1) {
            logger.error("db房源序号+1失败！使用本地生成序号");
            seqStr = StringUtil.leftZero(String.valueOf(getCommonFlowNoSeq()), 4);
            if (seqStr.length() > 4) {
                seqStr = seqStr.substring(seqStr.length() - 4);
            }
            return sb.append(seqStr).toString();
        }
        SSequence seq = sSequenceMapper.selectByPrimaryKey(seqId);
        int seqInt = seq.getScurrent().equals(seq.getSmin()) ? seq.getSmax() : seq.getScurrent() - 1;
        seqStr = StringUtil.leftZero(String.valueOf(seqInt), 4);
        return sb.append(seqStr).toString();
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public String genUserId() {
        StringBuilder sb = new StringBuilder(DateUtil.getDate("yyyyMMdd"));

        // 获取db序号
        String seqId = "USERID_SEQUENCE";
        String seqStr;
        int up = sSequenceMapper.increaseByPrimaryKey(seqId);
        if (up != 1) {
            logger.error("db用户ID序号+1失败！使用本地生成序号");
            seqStr = StringUtil.leftZero(String.valueOf(getCommonFlowNoSeq()), 4);
            if (seqStr.length() > 4) {
                seqStr = seqStr.substring(seqStr.length() - 4);
            }
            return sb.append(seqStr).toString();
        }
        SSequence seq = sSequenceMapper.selectByPrimaryKey(seqId);
        int seqInt = seq.getScurrent().equals(seq.getSmin()) ? seq.getSmax() : seq.getScurrent() - 1;
        seqStr = StringUtil.leftZero(String.valueOf(seqInt), 4);
        return sb.append(seqStr).toString();
    }

}
